﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using Utilities;

namespace Sovigaz.DataProvider
{
    public partial class SovigazDbContext : DbContext
    {
        public SovigazDbContext()
            : base("Default")
        {
            Database.SetInitializer<SovigazDbContext>(null);
        }

        public override int SaveChanges()
        {
            var modifiedEntries = ChangeTracker.Entries()
                .Where(x => x.Entity is IAuditableEntity
                            && (x.State == EntityState.Added || x.State == EntityState.Modified));

            foreach (var entry in modifiedEntries)
            {
                var entity = entry.Entity as IAuditableEntity;
                if (entity != null)
                {
                    int userID = Utility.UserID;

                    if (entry.State == EntityState.Added)
                    {
                        entity.CreatedBy = userID;
                        entity.CreatedDate = DateTime.Now;
                    }
                    else
                    {
                        Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                        Entry(entity).Property(x => x.CreatedDate).IsModified = false;
                    }

                    entity.UpdatedBy = userID;
                    entity.UpdatedDate = DateTime.Now;

                    List<Attribute> attrList = Attribute.GetCustomAttributes(entry.Entity.GetType()).ToList();
                    var attr = attrList.FirstOrDefault(p => p is TableAttribute) as TableAttribute;

                    var log = new Log
                    {
                        UserID = userID,
                        Content = ConvertUtility.XmlStringParse(entry.Entity),
                        Event = entry.State == EntityState.Added ? "Insert" : (entity.IsDeleted ? "Delete" : "Update"),
                        Table = attr == null ? String.Empty : attr.Name,
                        Date = DateTime.Now
                    };

                    Logs.Add(log);
                }
            }

            return base.SaveChanges();
        }

        public int SaveChanges(int userID)
        {
            var modifiedEntries = ChangeTracker.Entries()
                .Where(x => x.Entity is IAuditableEntity
                            && (x.State == EntityState.Added || x.State == EntityState.Modified));

            foreach (var entry in modifiedEntries)
            {
                var entity = entry.Entity as IAuditableEntity;
                if (entity != null)
                {
                    if (entry.State == EntityState.Added)
                    {
                        entity.CreatedBy = userID;
                        entity.CreatedDate = DateTime.Now;
                    }
                    else
                    {
                        Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                        Entry(entity).Property(x => x.CreatedDate).IsModified = false;
                    }

                    entity.UpdatedBy = userID;
                    entity.UpdatedDate = DateTime.Now;

                    List<Attribute> attrList = Attribute.GetCustomAttributes(entry.Entity.GetType()).ToList();
                    var attr = attrList.FirstOrDefault(p => p is TableAttribute) as TableAttribute;

                    var log = new Log
                    {
                        UserID = userID,
                        Content = ConvertUtility.XmlStringParse(entry.Entity),
                        Event = entry.State == EntityState.Added ? "Insert" : (entity.IsDeleted ? "Delete" : "Update"),
                        Table = attr == null ? String.Empty : attr.Name,
                        Date = DateTime.Now
                    };

                    Logs.Add(log);
                }
            }

            return base.SaveChanges();
        }

        //protected override void OnModelCreating(DbModelBuilder modelBuilder)
        //{
        //    modelBuilder.ComplexType<UserRoleComplex>();

        //    base.OnModelCreating(modelBuilder);
        //}
    }

    public abstract class GenericRepository
    {
        private int _pageCount;

        private int _pageNumber;

        protected SovigazDbContext _context = new SovigazDbContext();

        protected GenericRepository(string keyName)
        {
            KeyName = keyName;
        }

        public static int DefaultPageSize = 10;

        public string KeyName { get; set; }

        public int TotalItemCount { get; set; }

        public int TotalItemOnPage { get; set; }

        public int PageSize
        {
            get { return DefaultPageSize; }
        }

        public int PageCount
        {
            get { return _pageCount; }
            set
            {
                _pageCount = value;
                CalcPageList();
            }
        }

        public int PageNumber
        {
            get { return _pageNumber; }
            set
            {
                _pageNumber = value;
                CalcPageList();
            }
        }

        public List<string> PageList { get; set; }

        public void CalcPageList()
        {
            PageList = new List<string>();
            int i = _pageNumber - 2 > 0 ? _pageNumber - 2 : 1;
            for (; i <= _pageNumber + 2 && i <= _pageCount; i++)
            {
                PageList.Add(i.ToString());
            }
        }
    }
}